package com.valveinspectionsys.util;

import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

/**
 * 蓝牙读卡帮助类
 * @author king
 *
 */
public class BluetoothHelp {
	private static final String TAG = "BluetoothHelp";
	// 蓝牙适配器
	private BluetoothAdapter mBluetoothAdapter;
    private ProgressDialog mpd;
    private BluetoothDevice mBluetoothReader;
    private Context context;
 // 蓝牙读卡器设备标识
 	private static final String READER_NAME = "D-Think BPCD";
 	private static final String READER_PASSWORD = "1234";

 	// 消息标识符
 	public static final int MESSAGE_STATE_CHANGE = 1;
 	public static final int MESSAGE_READ = 2;
 	public static final int MESSAGE_WRITE = 3;
 	public static final int MESSAGE_DEVICE_NAME = 4;
 	public static final int MESSAGE_DIALOG = 5;
 	public static final String DIALOG = "dialog";
 	
 // 几个Task
 	private ConfigReaderTask mConfigReaderTask;// 配置读卡器
 	private ReadRfidCardTask mReadRfidCardTask;// 读卡
 	private EnableBluetoothDeviceTask mEnableBluetoothDeviceTask;// 开启蓝牙

 
 	// 读卡相关
 	private static final String RFID_CARD_START_WITH = "AA BB 0F";
	private static final int MODE_PRIVATE = 0;
 	
 	private BluetoothReaderCommunicationService mCommunicationService;
 	
 	private String rfidId;
 	
	public String getRfidId() {
		return rfidId;
	}


	public void setRfidId(String rfidId) {
		this.rfidId = rfidId;
	}


	public BluetoothHelp(Context context){
		this.context=context;	
	}
	
	
	public void start(){
		this.rfidId="";
		// 检查蓝牙设备
				if (mBluetoothAdapter == null) {
					Log.d(TAG, "没有找到蓝牙设备");
					new AlertDialog.Builder(context)
							.setCancelable(false)
							.setIcon(android.R.drawable.ic_dialog_info)
							.setTitle("警告")
							.setMessage("没有找到蓝牙设备")
							.setPositiveButton("确定",
									new DialogInterface.OnClickListener() {

										public void onClick(DialogInterface dialog,
												int which) {
											//通知用户开启蓝牙
											Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
											context.startActivity(intent);
										}
									});
				
				}

				// 获取已保存的读卡器
				mBluetoothReader = getPairedDevice();
				if (!mBluetoothAdapter.isEnabled()) {
					mEnableBluetoothDeviceTask = new EnableBluetoothDeviceTask();// 开启蓝牙
					mEnableBluetoothDeviceTask.execute(new Integer[] {});
					return;
				}
				if (mBluetoothReader != null) {
					connectRfidReader();
				} else {
					findRfidReader();// 扫描读卡器
				}
				
	}
	
	/**
	 * 初始化
	 */
	public void init(){

		// 初始化
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		mpd = new ProgressDialog(context);
		mpd.setCancelable(false);
		mCommunicationService = BluetoothReaderCommunicationService
				.defaultService(mHandler);

		// 添加蓝牙相关事件监听
		IntentFilter intent = new IntentFilter();
		intent.addAction(BluetoothDevice.ACTION_FOUND);// 查找到蓝牙监听
		intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);// 查找蓝牙结束监听
		intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); // 配对状态监听
		intent.addAction("android.bluetooth.device.action.PAIRING_REQUEST");// 监听蓝牙配对请求
		context.registerReceiver(mReceiver, intent);
		
	
		
	
	}
	
	private class ConfigReaderTask extends AsyncTask<Integer, Integer, Boolean> {

		@Override
		protected void onPreExecute() {
			mpd.setTitle(null);
			mpd.setMessage("正在配置读卡器，请稍后...");
			mpd.show();
		}

		@Override
		protected Boolean doInBackground(Integer... params) {
			Log.d(TAG, "蜂鸣");
			mCommunicationService.write(BluetoothMessageCenter.CONNECTED_BEEP);
			Log.d(TAG, "ISO15693");
			mCommunicationService.write(BluetoothMessageCenter.ISO15693_MODEL);
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			mpd.dismiss();
			readRfidCard();
		}
	}

	private class ReadRfidCardTask extends AsyncTask<Integer, Integer, String> {
		private Boolean shouldCancel = false;

		@Override
		protected void onPreExecute() {
			mpd.setTitle(null);
			mpd.setMessage("正在读卡，请稍后...");
			mpd.setCancelable(true);
			mpd.setOnCancelListener(new DialogInterface.OnCancelListener() {

				public void onCancel(DialogInterface dialog) {
					shouldCancel = true;
					
				}
			});
			mpd.show();
		}

		@Override
		protected String doInBackground(Integer... params) {
			String cardId = null;
			Log.d(TAG, "开天线");
			mCommunicationService.write(BluetoothMessageCenter.OPEN_AERIAL);
			while (true && shouldCancel == false) {
				Log.d(TAG, "读卡");
				String response = mCommunicationService
						.write(BluetoothMessageCenter.FIND_CARD);
				if (TextUtils.isEmpty(response)) {
					Log.d(TAG, "读卡器连接丢失");
					mCommunicationService.disConnect();
					return null;
				} else if (response.startsWith(RFID_CARD_START_WITH)) {
					Log.d(TAG, "读卡正确");
					mCommunicationService
							.writeWithOutResponse(BluetoothMessageCenter.READ_CARD_SUCCESS);
					cardId = response.substring(30, 54);
					break;
				}
			}
			Log.d(TAG, "关闭天线");
			mCommunicationService.write(BluetoothMessageCenter.CLOSE_AERIAL);
			return cardId;
		}

		@Override
		protected void onPostExecute(String cardId) {
			mpd.dismiss();
			if (!TextUtils.isEmpty(cardId)) {
				showCardId(cardId);
			}
		}
	}

	private class EnableBluetoothDeviceTask extends
			AsyncTask<Integer, Integer, Boolean> {

		private static final int miSLEEP_TIME = 150;
		private static final int miWATI_TIME = 20;
		private static final int mTRY_TIME = 3;
		private BluetoothAdapter adapter = mBluetoothAdapter;

		private EnableBluetoothDeviceTask() {
		}

		@Override
		protected void onPreExecute() {
			mpd.setTitle(null);
			mpd.setMessage("正在开启蓝牙设备，请稍后....");
			mpd.show();
		}

		@Override
		protected Boolean doInBackground(Integer... params) {
			Boolean res = false;
			for (int i = 0; i < mTRY_TIME; i++) {
				
				if (!adapter.isEnabled()) {
					//打开蓝牙设备
					adapter.enable();
				}

				for (int j = 0; j < miWATI_TIME; j++) {
					if (adapter.isEnabled()) {
						res = true;
						break;
					} else {
						try {
							Thread.sleep(miSLEEP_TIME);
						} catch (InterruptedException e) {
							break;
						}
					}
				}
			}

			return res;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			mpd.dismiss();
			if (result) {
				findRfidReader();
			} else {
				adapter.disable();
			AlertDialog dialog=	new AlertDialog.Builder(context)
						.setCancelable(false)
						.setIcon(android.R.drawable.ic_dialog_info)
						.setTitle("提示")
						.setMessage("蓝牙设备开启失败，请手动开启")
						.setPositiveButton("确定",
								new DialogInterface.OnClickListener() {

									public void onClick(DialogInterface dialog,
											int which) {
										dialog.cancel();
									}
								}).show();
			}
		}
	}
	
	private void findRfidReader() {
		mpd.setTitle(null);
		mpd.setMessage("正在寻找读卡器，请稍后....");
		mpd.show();

		if (mBluetoothAdapter.isDiscovering()) {
			mBluetoothAdapter.cancelDiscovery();
		}

		mBluetoothAdapter.startDiscovery();
	}

	private void connectRfidReader() {
		mBluetoothAdapter.cancelDiscovery();

		mpd.setTitle(null);
		mpd.setMessage("正在连接读卡器，请稍后....");
		mpd.show();

		if (mBluetoothReader.getBondState() == BluetoothDevice.BOND_NONE) {
			try {
				Log.d(TAG, "开始尝试配对");
				Method createBondMethod = BluetoothDevice.class
						.getMethod("createBond");
				createBondMethod.invoke(mBluetoothReader);
			} catch (Exception e) {
				Log.e(TAG, e.toString());
			}
		} else if (mCommunicationService.getState() != BluetoothReaderCommunicationService.STATE_CONNECTED) {
			synchronized (context) {
				mCommunicationService.connect(mBluetoothReader);
			}
		} else {
			readRfidCard();
		}
	}

	private void configReader() {
		mConfigReaderTask = new ConfigReaderTask();
		mConfigReaderTask.execute(new Integer[] {});
	}

	private void readRfidCard() {
		mReadRfidCardTask = new ReadRfidCardTask();
		mReadRfidCardTask.execute(new Integer[] {});
	}

	private BluetoothDevice getPairedDevice() {
		String mac = KsiSharedStorageHelper.getBluetoothMac(getPreferences());
		if (TextUtils.isEmpty(mac)) {
			return null;
		}
		BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mac);
		if (device == null) {
			return null;
		}
		if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
			KsiSharedStorageHelper.deleteBluetoothMac(getPreferences());
			return null;
		}
		return device;
	}

	
	private SharedPreferences getPreferences() {
		return context.getSharedPreferences(KsiSharedStorageHelper.BLUETOOTH_MAC,
				0);
	}



	private void connectionLost(String msg) {
		AlertDialog dialog=new AlertDialog.Builder(context).setTitle("警告")
				.setCancelable(false)
				.setIcon(android.R.drawable.ic_dialog_info).setMessage(msg)
				.setPositiveButton("确定", new DialogInterface.OnClickListener() {

					public void onClick(DialogInterface dialog, int which) {
						dialog.cancel();
					}
				}).show();
	}
	
	private void showCardId(String cardId) {

		Toast.makeText(context, cardId, Toast.LENGTH_LONG).show();
		
		this.rfidId=replaceBlank(cardId);
		
	}
	/**
	 * 去除空格
	 * @param str
	 * @return
	 */
	public static String replaceBlank(String str){
		String dest="";
		if(str!=null){
			Pattern p=Pattern.compile("\\s*|\t|\r|\n");
			Matcher m=p.matcher(str);
			dest=m.replaceAll("");
		}
		return dest;
	}
	private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();

			Log.d(TAG, action);

			if (BluetoothDevice.ACTION_FOUND.equals(action)) {
				BluetoothDevice device = intent
						.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
				Log.d(TAG, device.getName() + "");
				if (device.getName().equals(READER_NAME)) {
					mpd.dismiss();
					mBluetoothReader = device;
					mBluetoothAdapter.cancelDiscovery();
					KsiSharedStorageHelper.setBluetoothMac(
							context.getSharedPreferences(
									KsiSharedStorageHelper.BLUETOOTH_MAC,
									MODE_PRIVATE), device.getAddress());
					connectRfidReader();
				}
			} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
					.equals(action)) {
				mBluetoothAdapter.cancelDiscovery();
				if (mBluetoothReader == null) {
					mpd.dismiss();
				AlertDialog dialog=	new AlertDialog.Builder(context)
							.setCancelable(false)
							.setTitle("警告")
							.setIcon(android.R.drawable.ic_dialog_info)
							.setMessage("不能找到读卡器，请确认读卡器是否打开")
							.setPositiveButton("确定",
									new DialogInterface.OnClickListener() {

										public void onClick(
												DialogInterface dialog,
												int which) {
											dialog.dismiss();
										}
									}).show();
				}
			} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
				switch (mBluetoothReader.getBondState()) {
				case BluetoothDevice.BOND_BONDING:
					Log.d(TAG, "正在配对......");
					break;
				case BluetoothDevice.BOND_BONDED:
					Log.d(TAG, "完成配对");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						Log.e(TAG, e.toString());
					}
					mpd.dismiss();
					connectRfidReader();
					break;
				case BluetoothDevice.BOND_NONE:
					Log.d(TAG, "取消配对");
					mpd.dismiss();
				AlertDialog dialog=	new AlertDialog.Builder(context)
							.setCancelable(false)
							.setTitle("警告")
							.setIcon(android.R.drawable.ic_dialog_info)
							.setMessage("连接读卡器失败，请将读卡器关闭后再打开")
							.setPositiveButton("确定",
									new DialogInterface.OnClickListener() {

										public void onClick(
												DialogInterface dialog,
												int which) {
											dialog.dismiss();
										}
									}).show();

					break;
				default:
					Log.d(TAG, "未知行为");
					break;
				}
			} else if ("android.bluetooth.device.action.PAIRING_REQUEST"
					.equals(action)) {
				try {
					Method removeBondMethod = BluetoothDevice.class
							.getDeclaredMethod("setPin",
									new Class[] { byte[].class });
					removeBondMethod.invoke(mBluetoothReader,
							new Object[] { READER_PASSWORD.getBytes() });
				} catch (Exception e) {
					Log.e(TAG, e.toString());
				}

			}
		}
	};

	// The Handler that gets information back from the BluetoothChatService
	private final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MESSAGE_STATE_CHANGE:
				switch (msg.arg1) {
				case BluetoothReaderCommunicationService.STATE_CONNECTED:
					mpd.dismiss();
					Log.d(TAG, "已建立连接");
					configReader();
					break;
				case BluetoothReaderCommunicationService.STATE_CONNECTING:
					Log.d(TAG, "正在建立连接");
					break;
				}
				break;

			case MESSAGE_WRITE:
				String writeMessage = (String) msg.obj;
				Log.d(TAG, "Write_" + writeMessage);
				break;

			case MESSAGE_READ:
				String readMessage = (String) msg.obj;
			
				Log.d(TAG, "Read_" + readMessage);
				break;

			case MESSAGE_DIALOG:
				mpd.dismiss();
				connectionLost(msg.getData().getString(DIALOG));
				break;
			}
		}
	};


	/**
	 * 关闭
	 */
	 public void stop(){
		 close();
		//当Activity 被销毁是，取消所有的异步刷新
			if (mBluetoothAdapter != null) {
				mBluetoothAdapter.cancelDiscovery();
				
			}
			//保证广播资源被正确回收
			if(mReceiver!=null){
				context.unregisterReceiver(mReceiver);
				
			}
			

			if (mConfigReaderTask != null) {
				mConfigReaderTask.cancel(true);
			}

			if (mReadRfidCardTask != null) {
				mReadRfidCardTask.cancel(true);
			}

			if (mEnableBluetoothDeviceTask != null) {
				mEnableBluetoothDeviceTask.cancel(true);
			}

			if (mCommunicationService != null) {
				mCommunicationService.releaseHandler();
			}

	 }
	 
	 public void close(){
		 if(mpd.isShowing()){
			 mpd.dismiss();
		 }
	 }
}
